package com.qfedu.provider.service.impl;

import cn.hutool.core.util.RandomUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qfedu.config.RedisKeyConfig;
import com.qfedu.config.RocketmqConfig;
import com.qfedu.parm.LoginCodeParam;
import com.qfedu.parm.UserAdd;
import com.qfedu.parm.UserLogin;
import com.qfedu.provider.entity.DbUser;
import com.qfedu.provider.mapper.DbUserMapper;
import com.qfedu.provider.service.DbUserService;
import com.qfedu.provider.sms.AliSmsUtil;
import com.qfedu.utils.R;
import com.qfedu.utils.TokenUtil;
import com.qfedu.vo.UserFind;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @author Administrator
 * @description 针对表【db_user(用户表)】的数据库操作Service实现
 * @createDate 2024-11-23 11:16:39
 */
@Service
@Slf4j
public class DbUserServiceImpl extends ServiceImpl<DbUserMapper, DbUser>
        implements DbUserService {
    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Resource
    private DbUserMapper dbUserMapper;
    @Resource
    private RocketMQTemplate rocketMQTemplate;

//    @Override
//    public R findpass(DbUser dbUser) {
//        System.out.println("111111111111");
//        Object o = redisTemplate.opsForValue().get(RedisKeyConfig.SMS_PHONE);
//        System.out.println("o = " + o);
//        mapper.updateById(dbUser);
//         return R.ok("修改成功");
//    }


    @Override
    public R register(UserAdd parm) {
        //TODO 判空
        if (parm == null) {
            return R.error("参数为空");
        }
        LambdaQueryWrapper<DbUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(DbUser::getPhone, parm.getPhone()).or()
                .eq(DbUser::getNickName, parm.getNickName());
        //判断用户名或电话号码是否已存在
        if (dbUserMapper.selectOne(queryWrapper) != null) {
            return R.error("用户昵称或电话号码已存在");
        }
        DbUser dbUser = new DbUser();
        dbUser.setPhone(parm.getPhone());
        dbUser.setPassword(SecureUtil.sha1(SecureUtil.md5(parm.getPassword())));
        dbUser.setNickName(parm.getNickName());
        dbUserMapper.insert(dbUser);
        //发送消息,初始化用户详情表
        rocketMQTemplate.convertAndSend(RocketmqConfig.TOPIC_REGISTER, dbUser.getId());

        //log日志流水记录

        return R.ok("注册成功");
    }

    @Override
    public R loginpass(UserLogin user) {
        if (user == null) {
            return R.error("参数为空");
        }
        DbUser dbUser = dbUserMapper.selectOne(new LambdaQueryWrapper<DbUser>()
                .eq(DbUser::getPhone, user.getPhone())
                .eq(DbUser::getPassword, SecureUtil.sha1(SecureUtil.md5(user.getPassword()))));
        if (dbUser == null) {
            return R.error("用户名或密码错误");
        }
        //TODO 校验账号是否已经注销
        if (dbUser.getDeleted() != 1) {
            return R.error("账号已注销");
        }
        //TODO 校验账号状态
        if (!dbUser.getStatus().equals("1")) {
            return R.error("账号状态异常");
        }
        //校验唯一性
        if (stringRedisTemplate.hasKey(RedisKeyConfig.AUTH_PHONE + dbUser.getPhone())) {
            //已经有账号在线
            return R.error("账号已在其他设备登录");
        }
        //TODO 生成token
        String token = TokenUtil.createToken(dbUser.getPhone());
        //存储token
        stringRedisTemplate.opsForValue().set(RedisKeyConfig.AUTH_TOKEN + token, JSONUtil.toJsonStr(dbUser), RedisKeyConfig.AUTH_TOKEN_TIME, TimeUnit.DAYS);
        //存入redis,有效期30分钟,唯一性登录的标志
        stringRedisTemplate.opsForValue().set(RedisKeyConfig.AUTH_PHONE + dbUser.getPhone(), token, RedisKeyConfig.AUTH_TOKEN_TIME, TimeUnit.MINUTES);

        Map<String, Object> map = new HashMap<>();
        map.put("token", token);
        map.put("user", dbUser);
        return R.ok(map);
    }

    @Override
    public R sendcode(String phone) {
        String code = RandomUtil.randomNumbers(6);
        if (AliSmsUtil.sendCode(AliSmsUtil.TEM_LCODE, phone, code)) {
            System.out.println("发送成功");
            stringRedisTemplate.opsForValue().set(
                    RedisKeyConfig.LOGIN_CODE + phone,
                    code,
                    RedisKeyConfig.CODE_LIVE_TIME,
                    TimeUnit.MINUTES);
            //   DbUser user = dbUserMapper.selectOne(new LambdaQueryWrapper<DbUser>().eq(DbUser::getPhone, phone));
            /*Integer uid = 0;
            if (user != null) {
                uid = user.getId();
            }*/
            //  logDao.insert(new LhUserLog(uid, "发送登录验证码", ip, "登录验证码发送成功！"));
            return R.ok(code);
        } else {
            return R.error("sorry,网络异常，请稍后重试！");
        }
    }


    /*验证码·登录*/
    @Override
    public R logincode(LoginCodeParam parm) {
        //校验验证码
        String code = stringRedisTemplate.opsForValue().get(RedisKeyConfig.LOGIN_CODE + parm.getPhone());
        if (code == null) {
            return R.error("验证码已过期");
        }
        DbUser dbUser = dbUserMapper.selectOne(new LambdaQueryWrapper<DbUser>().eq(DbUser::getPhone, parm.getPhone()));
        if (dbUser == null) {
            log.info("用户不存在");
            DbUser dbUser1 = new DbUser();
            dbUser1.setPhone(parm.getPhone());
            //随机昵称
            dbUser1.setNickName(RandomUtil.randomString(6));
            //默认密码123456
            dbUser1.setPassword(SecureUtil.sha1(SecureUtil.md5("123456")));
            if (dbUserMapper.insert(dbUser1) <= 0) {
                return R.error("注册失败");
            }
            rocketMQTemplate.convertAndSend(RocketmqConfig.TOPIC_REGISTER, dbUser1.getId());
            //TODO 注册成功,插入日志

            System.out.println("注册成功");
        }
        //已经找到了这个电话号码
        //检测账号状态
        DbUser dbUser2 = dbUserMapper.selectOne(new LambdaQueryWrapper<DbUser>().eq(DbUser::getPhone, parm.getPhone()));

        if (dbUser2.getDeleted() != 1) {
            return R.error("账号已注销");
        }
        if (!"1".equals(dbUser2.getStatus())) {
            return R.error("账号状态异常");
        }
        //校验唯一性
        if (stringRedisTemplate.hasKey(RedisKeyConfig.AUTH_PHONE + dbUser2.getPhone())) {
            return R.error("账号已在其他设备登录");
        }
        //生成token
        String token = TokenUtil.createToken(dbUser2.getPhone());
        //存储token
        stringRedisTemplate.opsForValue().set(RedisKeyConfig.AUTH_TOKEN + token, JSONUtil.toJsonStr(dbUser2), RedisKeyConfig.AUTH_TOKEN_TIME, TimeUnit.DAYS);
        //唯一性登录标志
        stringRedisTemplate.opsForValue().set(RedisKeyConfig.AUTH_PHONE + dbUser2.getPhone(), token, RedisKeyConfig.AUTH_TOKEN_TIME, TimeUnit.MINUTES);

        //返回数据
        Map<String, Object> map = new HashMap<>();
        map.put("token", token);
        map.put("user", dbUser2);
        return R.ok(map);
    }

    @Override
    public R logout(String token) {
        if (token != null) {
            String phone = TokenUtil.parseToken(token);
            stringRedisTemplate.delete(RedisKeyConfig.AUTH_TOKEN + token);
            stringRedisTemplate.delete(RedisKeyConfig.AUTH_PHONE + phone);

            // TODO 退出登录,插入日志
            return R.ok("退出成功");
        }
        return R.error("退出失败");
    }

    @Override
    public R findpass(UserFind userFind) {
        if (userFind.getPhone() == null) {
            return R.error("手机号不能为空");
        }
        if (userFind.getCode() == null) {
            return R.error("验证码不能为空");
        }

        if (userFind.getPhone().length() != 11) {
            return R.error("手机号格式不正确");
        }
        if (userFind.getPassword().length() < 6) {
            return R.error("密码长度不能小于6位");
        }
        LambdaQueryWrapper<DbUser> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DbUser::getPhone, userFind.getPhone());
        if (dbUserMapper.selectOne(wrapper) == null) {
            return R.error("用户不存在");
        }
        String key = RedisKeyConfig.SMS_CODE + userFind.getPhone();
        if (!stringRedisTemplate.hasKey(key)) {
            return R.error("验证码已过期");
        }
        if (stringRedisTemplate.opsForValue().get(key).equals(userFind.getCode())) {
            DbUser dbUser = dbUserMapper.selectOne(new LambdaQueryWrapper<DbUser>().eq(DbUser::getPhone, userFind.getPhone()));
            if (userFind.getPassword() == null) {
                return R.error("密码不能为空");
            }
            if (userFind.getRePassword() == null) {
                return R.error("确认密码不能为空");
            }
            if (!userFind.getPassword().equals(userFind.getRePassword())) {
                return R.error("两次密码不一致");
            }
            String password = SecureUtil.sha1(SecureUtil.md5(userFind.getPassword()));
            dbUser.setPassword(password);
            if (dbUserMapper.updateById(dbUser) > 0) {
                return R.ok("修改密码成功");
            }
            return R.error("修改密码失败");
        }
        return R.error("验证码错误");
       /* System.out.println("111111111111111111111111");
        String key = RedisKeyConfig.SMS_CODE + userFind.getPhone();
        System.out.println(stringRedisTemplate.hasKey(RedisKeyConfig.SMS_CODE + userFind.getPhone()));
        if (stringRedisTemplate.opsForValue().get(key).equals(userFind.getCode())) {

            DbUser dbUser = dbUserMapper.selectOne(new LambdaQueryWrapper<DbUser>().eq(DbUser::getPhone, userFind.getPhone()));
            if (dbUser != null) {
                return R.error("用户已存在");
            }

           *//* if (dbUserMapper.insert(new DbUser(userFind.getPhone()))>0) {
                log.info("注册成功");

            }*//*

            String password = SecureUtil.sha1(SecureUtil.md5(userFind.getPassword()));

            String rePassword = SecureUtil.sha1(SecureUtil.md5(userFind.getRePassword()));
            if (password.equals(rePassword)) {
                dbUser.setPassword(password);
                dbUser.setUpdateTime(new Date());
            }

            if (dbUserMapper.updateById(dbUser) <= 0) {
                return R.ok("修改失败");

            }
        }
        return R.error("修改成功");*/
    }
}




